1. 处理流程
- 请求提交给
DispatchServlet
- 查找
HandlerMapping
- 调用由
HandlerAdapter
封装后的Handler
- 返回
ModelAndView
到DispatcherServlet
- 借由
ViewResolver
完成逻辑视图到真实视图的转换 - 返回响应
2. 配置 DispatcherServlet
web.xml
1 | <web-app> |
- 子容器可以访问父容器的 bean,父容器不能访问子容器的 bean
- 默认采用
org.springframework.web.context.ContextLoaderListener
- 默认使用
/WEB-INF/{servlet-name}-*.xml
加载子容器
3. DispatcherServlet 的初始化
DispatcherServlet
初始化
1 | protected void initStrategies(ApplicationContext context) { |
- 默认配置:
DispatcherServlet.properties
1 | # Default implementation classes for DispatcherServlet's strategy interfaces. |
4. Controller 注解
4.1 类注解
@Controller
(由 Spring 识别Handler
实例)@RequestMapping(value=, method=, params=)
4.2 方法注解
@RequestMapping(value=, method=, params=)
@PathVariable
,配合占位符{parameter}
@RequestParam(value=, required=, defaultValue=)
@CookieValue(value=, required=, defaultValue=)
@RequestHeader(value=, required=, defaultValue=)
5. 封装入参
HttpServletRequest
,WebRequest
,ServletRequest
的InputStream
/Reader
HttpServeltResponse
,ServletResponse的OutputStream
/Writer
6. 请求信息和对象的转换
6.1 基本
HttpMessageConverter<T>
- 使用
@RequestBody
/@ResponseBody
;使用HttpEntity<T>
/ResponseEntity<T>
- Spring 根据 HTTP 报文头部的
Accept
指定的 MIME 类型,查找匹配的HttpMessageConverter
- Spring MVC 默认装配
AnnotationMethodHandlerAdapter
,调用HttpMessageConverter
- MVC 命名空间的
<mvc:annotation-driven/>
标签会创建并注册一个默认的DefaultAnnotationHandlerMapping
和一个AnnotationMethodHandlerAdapter
实例,如果上下文中存在自定义的对应组件 bean,则覆盖默认配置
6.2 样例
app-servlet.xml
1 | <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"> |
7. 处理模型数据
- Spring MVC 在调用方法前会创建一个隐含的模型对象
ModelAndView
:返回值类型为ModelAndView
时,方法体通过该对象添加模型数据@ModelAttribute
:入参对象添加到数据模型中- Map 和 Model:入参为
org.springframework.ui.Model
、org.springframework.ui.ModelMap
或java.util.Map
时,处理方法返回时,Map 中的数据会自动添加到模型中 @SessionAttributes
:将模型中的某个属性暂存到HttpSession
中,以便多个请求共享
8. 数据绑定
8.1 基本
- Spring MVC 将
ServletRequest
对象及处理方法的入参实例传递给DataBinder
; DataBinder
调用ConversionService
组件进行数据类型转换、数据格式化等工作,将ServletRequest
中的消息填充到入参对象中;- 然后再调用
Validator
组件对已经绑定了请求消息数据的入参对象进行数据合法性校验,并最终生成绑定结果BindingResult
对象,其中还包含相应的校验错误对象 - 抽取
BindingResult
中的入参对象及校验错误对象,赋给处理方法的相应入参
8.2 数据转换
- 例如:将请求信息中A类型参数转换并绑定到 Controller 对应的处理方法的 B 类型入参中
- 基于
ConversionService
接口,Spring 将自动识别其实现类,用于入参类型转换,类似于 C++ 中的自定义类型转换。例如,将 HTTP 请求信息中的字符串格式参数转换为 Controller 对应方法中的类类型入参 - 可通过
ConversionServiceFactoryBean
的converters
属性注册自定义转换器。可接受Converter
,ConverterFacotory
,GenericConverter
或ConditionalConverterFactory
的实现类,并统一封装到一个ConversionService
的实例(即GenericConversionService
)中
1 | <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> |
<mvc:annotation-driven/>
标签还会注册一个默认的ConversionService
,即FormattingConversionServiceFactoryBean
8.3 数据格式化
- 例如:将请求信息中字符串类型参数转换并绑定到 Controller 对应的处理方法入参中的 Date 类型属性中
- 格式化框架定义了
Formatter<T>
接口,扩展于Printer<T>
和Parser<T>
接口 - Srping 提供
AnnotationFormatterFactory<A extends Annotation>
接口及两个实现类:NumberFormatAnnotationFormatterFactory
和JodaDateTimeFormatAnnotationFormatterFactory
- 在入参类属性上使用注解:
@DateTimeFormat
,@NumberFormat
- Spring 通过
<mvc:annotation-driven/>
标签创建FormattingConversionServiceFactoryBean
作为FormattingConversionService
的实例,自动装配NumberFormatAnnotationFormatterFactory
和JodaDateTimeFormatAnnotationFormatterFactory
8.4 数据验证
<mvc:annotation-driven/>
标签会默认装配LocalValidatorFactoryBean
,实现了 Spring 的Validator
接口,通过在入参上标注@Valid
注解即可让 Spring 在完成数据绑定后执行数据校验@Valid
注解标注的入参和其后的BindingResult
或Errors
入参成对出现,后者保存前者的校验结果- 校验结果也保存在 MVC 的隐含模型中
- 样例
1 | public Class User { |
9. 视图解析
9.1 基本
- 视图对象是一个 bean,由视图解析器负责实例化。
- 不同的视图实现技术对应于不同的
View
实现类 - 所有的视图解析器都实现了
ViewResolver
接口
9.2 样例
app-servlet.xml
1 | <!-- For multipart encoding support --> |
10. 静态资源处理
- 需要对项目中的图片、html 静态资源等单独处理
- 配置
<mvc:default-servlet-handler>
后,会装配一个DefaultServletHttpRequestHandler
,对静态资源做检查 - 配置
<mvc:resources/>
,允许对静态资源文件路径作映射,并提供文件在浏览器端的缓存控制,例如
1 | <mvc:resources mapping="/resources/**" location="/,classpath:/META-INF/publicResources" /> |
11. 拦截器
11.1 基本
DispatcherServlet
将请求交给处理器映射(HandlerMapping
),找到对应的HandlerExecutionChain
- 找到对应的
HandlerExecutionChain
包含若干HandlerInterceptor
,和一个Handler
HandlerInterceptor
接口:
1 | public interface HandlerInterceptor { |
11.2 样例
app-servlet.xml
:
1 | <mvc:interceptors> |
12. 异常处理
12.1 基本
- Spring MVC 通过
HandlerExceptionResolver
处理异常 HandlerExceptionResolver
接口:
1 | public interface HandlerExceptionResolver { |
- Spring MVC 默认装配了
DefaultHandlerExceptionResolver
- Spring MVC 默认注册了
AnnotationMethodHandlerExceptionResolver
,允许通过@ExceptionHandler
指定处理特定异常
12.2 样例
web.xml
1 | <web-app> |